package cn.biao.epic.sys.core.constant.factory;

import cn.biao.epic.core.util.SpringContextHolder;
import cn.biao.epic.core.util.ToolUtil;
import cn.biao.epic.sys.core.constant.state.ManagerStatus;
import cn.biao.epic.sys.core.constant.state.MenuStatus;
import cn.biao.epic.sys.modular.system.entity.*;
import cn.biao.epic.sys.modular.system.mapper.*;
import cn.biao.epic.sys.modular.system.service.PositionService;
import cn.biao.epic.sys.modular.system.service.UserPosService;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Auther Uncle_Z
 * @date 2019/12/10 9:41
 * @Email:2545375@qq.com
 * @Descrition
 */
@Component
@DependsOn("springContextHolder")
public class ConstantFactory implements IConstantFactory {

    private RoleMapper roleMapper = SpringContextHolder.getBean(RoleMapper.class);
    private DeptMapper deptMapper = SpringContextHolder.getBean(DeptMapper.class);
    private DictMapper dictMapper = SpringContextHolder.getBean(DictMapper.class);
    private DictTypeMapper dictTypeMapper = SpringContextHolder.getBean(DictTypeMapper.class);
    private UserMapper userMapper = SpringContextHolder.getBean(UserMapper.class);
    private MenuMapper menuMapper = SpringContextHolder.getBean(MenuMapper.class);
    private NoticeMapper noticeMapper = SpringContextHolder.getBean(NoticeMapper.class);
    private UserPosService userPosService = SpringContextHolder.getBean(UserPosService.class);
    private PositionService positionService = SpringContextHolder.getBean(PositionService.class);

    public static IConstantFactory me(){
        return SpringContextHolder.getBean("constantFactory");
    }

    @Override
    public String getUserNameById(Long userId) {
        Optional<User> optionalUser = Optional.ofNullable(
                userMapper.selectById(userId)
        );
        Optional<String> optAcc = optionalUser.map(User::getName);
        return optAcc.orElse("--");
    }

    @Override
    public String getUserAccountById(Long userId) {
        Optional<User> optionalUser = Optional.ofNullable(
                userMapper.selectById(userId)
        );
        Optional<String> optAcc = optionalUser.map(User::getAccount);
        return optAcc.orElse("--");
    }

    @Override
    public String getRoleName(String roleIds) {
        if (ToolUtil.isEmpty(roleIds)) {
            return "";
        }
        Long[] roles = Convert.toLongArray(roleIds);
        StringBuilder sb = new StringBuilder();
        for (long role : roles) {
            Role roleObj = roleMapper.selectById(role);
            if (ToolUtil.isNotEmpty(roleObj) && ToolUtil.isNotEmpty(roleObj.getName())) {
                sb.append(roleObj.getName()).append(",");
            }
        }
        return StrUtil.removeSuffix(sb.toString(), ",");
    }

    @Override
    public String getSingleRoleName(Long roleId) {
        if(roleId ==0){
            return "--";
        }
        Role roleObj = roleMapper.selectById(roleId);
        if (ToolUtil.isNotEmpty(roleObj) && ToolUtil.isNotEmpty(roleObj.getName())) {
            return roleObj.getName();
        }
        return "";
    }

    @Override
    public String getSingleRoleTip(Long roleId) {
        if (roleId==0) {
            return "--";
        }
        Role roleObj = roleMapper.selectById(roleId);
        if (ToolUtil.isNotEmpty(roleObj) && ToolUtil.isNotEmpty(roleObj.getDescription())) {
            return roleObj.getDescription();
        }
        return "";
    }

    @Override
    public String getDeptName(Long deptId) {
        if (deptId == null) {
            return "";
        }else if(deptId==0){
            return "顶级";
        } else{
            Dept dept = deptMapper.selectById(deptId);
            if (ToolUtil.isNotEmpty(dept) && ToolUtil.isNotEmpty(dept.getFullName())) {
                return dept.getFullName();
            }
            return "";
        }
    }

    @Override
    public String getMenuNames(String menuIds) {
        Long[] menus = Convert.toLongArray(menuIds);
        StringBuilder sb = new StringBuilder();
        for (Long id : menus) {
            Menu menu = menuMapper.selectById(id);
            if (ToolUtil.isNotEmpty(menu) && ToolUtil.isNotEmpty(menu.getName())) {
                sb.append(menu.getName()).append(",");
            }
        }
        return StrUtil.removeSuffix(sb.toString(), ",");
    }

    @Override
    public String getMenuName(Long menuId) {
        if (ToolUtil.isEmpty(menuId)) {
            return "";
        }else{
            Menu menu = menuMapper.selectById(menuId);
            if (menu==null) {
                return "";
            }else{
                return menu.getName();
            }
        }
    }

    @Override
    public Menu getMenuByCode(String code) {
        if (ToolUtil.isEmpty(code)) {
            return new Menu();
        } else if (code.equals("0")){
            return new Menu();
        } else {
            Menu param = new Menu();
            param.setCode(code);
            QueryWrapper<Menu> queryWrapper = new QueryWrapper<>(param);
            Menu menu = menuMapper.selectOne(queryWrapper);
            if (menu == null) {
                return new Menu();
            }else{
                return menu;
            }
        }
    }

    @Override
    public String getMenuNameByCode(String code) {
        if (ToolUtil.isEmpty(code)) {
            return "";
        } else if (code.equals("0")){
            return "顶级";
        } else {
            Menu param = new Menu();
            param.setCode(code);
            QueryWrapper<Menu> queryWrapper = new QueryWrapper<>(param);
            Menu menu = menuMapper.selectOne(queryWrapper);
            if (menu == null) {
                return "";
            }else{
                return menu.getName();
            }
        }
    }

    @Override
    public Long getMenuIdByCode(String code) {
        if (ToolUtil.isEmpty(code)) {
            return 0L;
        } else if (code.equals("0")) {
            return 0L;
        } else {
            Menu menu = new Menu();
            menu.setCode(code);
            QueryWrapper<Menu> queryWrapper = new QueryWrapper<>(menu);
            Menu tempMenu = this.menuMapper.selectOne(queryWrapper);
            return tempMenu.getMenuId();
        }
    }

    @Override
    public String getDictName(Long dictId) {
        if (ToolUtil.isEmpty(dictId)) {
            return "";
        } else {
            Dict dict = dictMapper.selectById(dictId);
            if (dict == null) {
                return "";
            } else {
                return dict.getName();
            }
        }
    }

    @Override
    public String getNoticeTitle(Long dictId) {
        if (ToolUtil.isEmpty(dictId)) {
            return "";
        } else {
            Notice notice = noticeMapper.selectById(dictId);
            if (notice == null) {
                return "";
            } else{
                return notice.getTitle();
            }
        }
    }

    @Override
    public String getDictsByName(String name, String code) {
        DictType temp = new DictType();
        temp.setName(name);
        QueryWrapper<DictType> tWrapper = new QueryWrapper<>(temp);
        DictType dictType = dictTypeMapper.selectOne(tWrapper);
        if (dictType == null) {
            return "";
        } else{
            QueryWrapper<Dict> dWrapper = new QueryWrapper<>();
            dWrapper = dWrapper.eq("dict_type_id", dictType.getDictTypeId());
            List<Dict> dictList = dictMapper.selectList(dWrapper);
            Optional<String> opStr = dictList.stream().map(Dict::getCode)
                    .filter(v -> ToolUtil.isNotEmpty(v) && v.equals(code))
                    .findFirst();
            return opStr.orElse("");
        }
    }

    @Override
    public String getDictNameByCode(String dictCode) {
        if (ToolUtil.isEmpty(dictCode)) {
            return "";
        } else{
            QueryWrapper<Dict> dWrapper = new QueryWrapper<>();
            dWrapper.eq("code", dictCode);
            Optional<Dict> optionalDict = Optional.ofNullable(dictMapper.selectOne(dWrapper)) ;
            Optional<String> strOpt = optionalDict.map(Dict::getName);
            return strOpt.orElse("");
        }
    }

    @Override
    public String getSexName(String sexCode) {
        return getDictsByName("性别",sexCode);
    }

    @Override
    public String getStatusName(String status) {
        return ManagerStatus.getDescription(status);
    }

    @Override
    public String getMenuStatusName(String status) {
        return MenuStatus.getDescription(status);
    }

    @Override
    public List<Dict> findInDict(Long id) {
        if (ToolUtil.isEmpty(id)) {
            return null;
        } else {
            QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();
            List<Dict> dictList = dictMapper.selectList(dictQueryWrapper.eq("pid", id));
            if (dictList == null || dictList.size()==0) {
                return null;
            } else {
                return dictList;
            }
        }
    }

    @Override
    public String getCacheObject(String para) {
        return null;
    }

    @Override
    public List<Long> getSubDeptId(Long deptId) {
        ArrayList<Long> deptIds = new ArrayList<>();

        if (deptId ==0) {
            return deptIds;
        } else {
            List<Dept> depts = deptMapper.likePids(deptId);
            if (depts != null && depts.size()>0) {
                return depts.stream().map(Dept::getDeptId)
                        .collect(Collectors.toList());
            }
        }
        return deptIds;
    }

    @Override
    public List<Long> getParentDeptIds(Long deptId) {
        Dept dept = deptMapper.selectById(deptId);
        String pids = dept.getPids();
        String[] splits = pids.split(",");
        return Arrays.stream(splits).map(v -> Long.valueOf(StrUtil.removeSuffix(
                StrUtil.removePrefix(v,"["),"]"
        )))
        .collect(Collectors.toList());
    }

    @Override
    public String getPositionName(Long userId) {
        StringBuilder sb = new StringBuilder();
        List<UserPos> userPosList = userPosService.list(
                new QueryWrapper<UserPos>().eq("user_id",userId)
        );
        if (userPosList != null && userPosList.size()>0) {
            userPosList.forEach(v ->{
                Position position = positionService.getById(v.getPosId());
                if (position != null) {
                    sb.append(",").append(position.getName());
                }
            });
        }
        return StrUtil.removeSuffix(sb.toString(), ",");
    }

    @Override
    public String getPositionIds(Long userId) {
        StringBuilder posIds = new StringBuilder();
        List<UserPos> userPosList = userPosService.list(
                new QueryWrapper<UserPos>().eq("user_id",userId)
        );
        if (userPosList != null && userPosList.size() > 0) {
            userPosList.forEach(v ->{
                Position position = positionService.getById(v.getPosId());
                if (position != null) {
                    posIds.append(",").append(position.getPositionId());
                }
            });
        }
        return StrUtil.removePrefix(posIds.toString(),",");
    }
}
